package v1

import (
	"context"
	"strings"
	"time"

	"wxpay/internal/conf"
	"wxpay/internal/dto"
	"wxpay/internal/service"
	wxpay "wxpay/pkg/api/v1"
	"wxpay/pkg/merrors"
	"wxpay/pkg/util"

	"github.com/aliyun/aliyun-oss-go-sdk/oss"
)

// request to dto
func (s *Server) convertLicenseDTO(ctx context.Context, info *wxpay.BizLicenseInfo) (r *dto.BusinessLicenseInfoDTO, err error) {
	const op merrors.Op = "convertLicenseDTO"
	if info == nil {
		return
	}
	objName, err := s.redis.Get(ctx, info.BusinessLicenseCopy).Result()
	if err != nil || objName == "" {
		return nil, merrors.E(op, merrors.Invalid, merrors.ErrRedisClient, "找不到对应资源的cos对象名称")
	}
	r = &dto.BusinessLicenseInfoDTO{
		BusinessLicenseCopy:   info.BusinessLicenseCopy,
		CopyOssName:           objName,
		BusinessLicenseNumber: info.BusinessLicenseNumber,
		MerchantName:          info.MerchantName,
		LegalPerson:           info.LegalPerson,
		CompanyAddress:        info.CompanyAddress,
		BusinessTime:          info.BusinessTime,
	}
	return
}

// request to dto
func (s *Server) convertCertDTO(ctx context.Context, info *wxpay.OrganizationCertInfo) (r *dto.OrganizationCertInfoDTO, err error) {
	const op merrors.Op = "convertCertDTO"
	if info == nil {
		return
	}
	objName, err := s.redis.Get(ctx, info.OrganizationCopy).Result()
	if err != nil || objName == "" {
		return nil, merrors.E(op, merrors.Invalid, merrors.ErrRedisClient, "找不到对应资源的cos对象名称")
	}
	r = &dto.OrganizationCertInfoDTO{
		OrganizationCopy:   info.OrganizationCopy,
		CopyOssName:        objName,
		OrganizationNumber: info.OrganizationNumber,
		OrganizationTime:   info.OrganizationTime,
	}
	return
}

// request to dto
func (s *Server) convertCardInfoDTO(ctx context.Context, info *wxpay.IDCardInfo) (r *dto.IDCardInfoDTO, err error) {
	const op merrors.Op = "convertCardInfoDTO"
	if info == nil {
		return
	}
	cardObjName, err := s.redis.Get(ctx, info.IdCardCopy).Result()
	if err != nil || cardObjName == "" {
		return nil, merrors.E(op, merrors.Invalid, merrors.ErrRedisClient, "找不到对应资源的cos对象名称")
	}
	nationalObjName, err := s.redis.Get(ctx, info.IdCardNational).Result()
	if err != nil || nationalObjName == "" {
		return nil, merrors.E(op, merrors.Invalid, merrors.ErrRedisClient, "找不到对应资源的cos对象名称")
	}
	r = &dto.IDCardInfoDTO{
		IDCardCopy:          info.IdCardCopy,
		CardCopyOssName:     cardObjName,
		IDCardNational:      info.IdCardNational,
		NationalCopyOssName: nationalObjName,
		IDCardName:          info.IdCardName,
		IDCardNumber:        info.IdCardNumber,
		IDCardValidTime:     info.IdCardValidTime,
	}
	return
}

// request to dto
func (s *Server) convertDocInfoDTO(ctx context.Context, info *wxpay.IDDocInfo) (r *dto.IDDocInfoDTO, err error) {
	const op merrors.Op = "convertDocInfoDTO"
	if info == nil {
		return
	}
	objName, err := s.redis.Get(ctx, info.IdDocCopy).Result()
	if err != nil || objName == "" {
		return nil, merrors.E(op, merrors.Invalid, merrors.ErrRedisClient, "找不到对应资源的cos对象名称")
	}
	r = &dto.IDDocInfoDTO{
		IDDocName:    info.IdDocName,
		IDDocNumber:  info.IdDocNumber,
		IDDocCopy:    info.IdDocCopy,
		CopyOssName:  objName,
		DocPeriodEnd: info.DocPeriodEnd,
	}
	return
}

// request to dto
func convertAccountInfoDTO(info *wxpay.AccountInfo) (r *dto.AccountInfoDTO) {
	if info == nil {
		return
	}
	r = &dto.AccountInfoDTO{
		BankAccountType: info.BankAccountType,
		AccountBank:     info.AccountBank,
		AccountName:     info.AccountName,
		BankAddressCode: info.BankAddressCode,
		BankBranchID:    info.BankBranchId,
		BankName:        info.BankName,
		AccountNumber:   info.AccountNumber,
	}
	return
}

// request to dto
func convertContactInfo(info wxpay.ContactInfo) (r dto.ContactInfoDTO) {
	r = dto.ContactInfoDTO{
		ContactType:         info.ContactType,
		ContactName:         info.ContactName,
		ContactIDCardNumber: info.ContactIdCardNumber,
		MobilePhone:         info.MobilePhone,
		ContactEmail:        info.ContactEmail,
	}
	return
}

// request to dto
func convertSalesSceneInfoDTO(info wxpay.SalesSceneInfo) (r dto.SalesSceneInfoDTO) {
	r = dto.SalesSceneInfoDTO{
		StoreName:           info.StoreName,
		StoreUrl:            info.StoreUrl,
		StoreQrCode:         info.StoreQrCode,
		MiniProgramSubAppID: info.MiniProgramSubAppid,
	}
	return
}

func (s *Server) buildApplyDtoFromRequest(ctx context.Context, req *wxpay.ApplymentSubmitRequest) (apply *dto.ApplymentDTO, err error) {
	blinfo, err := s.convertLicenseDTO(ctx, req.BizLicenseInfo)
	if err != nil {
		return nil, err
	}
	orgInfo, err := s.convertCertDTO(ctx, req.OrganizationCertInfo)
	if err != nil {
		return nil, err
	}
	cardInfo, err := s.convertCardInfoDTO(ctx, req.IdCardInfo)
	if err != nil {
		return nil, err
	}
	docInfo, err := s.convertDocInfoDTO(ctx, req.IdDocInfo)
	if err != nil {
		return nil, err
	}
	info := dto.ApplymentInfoDTO{
		OrganizationType:     req.OrganizationType,
		BusinessLicenseInfo:  blinfo,
		OrganizationCertInfo: orgInfo,
		IDDocType:            req.IdDocType,
		IDCardInfo:           cardInfo,
		IDDocInfo:            docInfo,
		NeedAccountInfo:      req.NeedAccountInfo,
		AccountInfo:          convertAccountInfoDTO(req.AccountInfo),
		ContactInfo:          convertContactInfo(*req.ContactInfo),
		SalesSceneInfo:       convertSalesSceneInfoDTO(*req.SalesSceneInfo),
		MerchantShortname:    req.MerchantShortname,
		Qualifications:       req.Qualifications,
		BusinessAdditionPics: req.BusinessAdditionPics,
		BusinessAdditionDesc: req.BusinessAdditionDesc,
	}
	apply = &dto.ApplymentDTO{
		BizApplyNo:    req.BizApplyNo,
		BrandID:       req.BrandId,
		MchID:         req.MchId,
		ApplymentType: req.ApplyType,
		ApplymentInfo: &info,
		CreateTime:    util.GetNow(),
		UpdateTime:    util.GetNow(),
	}
	return
}

// 提交申请 POST /api/v1/wxpay/applyment/submit
func (s *Server) ApplymentSubmit(ctx context.Context, req *wxpay.ApplymentSubmitRequest) (*wxpay.ApplymentSubmitResponse, error) {
	op := merrors.Op("ApplymentSubmit")
	applyDto, err := s.buildApplyDtoFromRequest(ctx, req)
	if err != nil {
		return nil, err
	}
	res, err := service.NewApplymentService(s.d).Submit(ctx, applyDto)
	if err != nil {
		return nil, merrors.E(op, merrors.Invalid, err)
	}
	return &wxpay.ApplymentSubmitResponse{ApplyNo: res.ApplyNo}, nil
}

// 修改申请重新提交
func (s *Server) ApplymentReSubmit(ctx context.Context, req *wxpay.ApplymentSubmitRequest) (*wxpay.ApplymentSubmitResponse, error) {
	op := merrors.Op("ApplymentSubmit")
	applyDto, err := s.buildApplyDtoFromRequest(ctx, req)
	if err != nil {
		return nil, err
	}
	res, err := service.NewApplymentService(s.d).ReSubmit(ctx, applyDto)
	if err != nil {
		return nil, merrors.E(op, merrors.Invalid, err)
	}
	return &wxpay.ApplymentSubmitResponse{ApplyNo: res.ApplyNo}, nil
}

func buildOssUrl(objName string) (signUrl string) {
	if objName == "" {
		return ""
	}
	if strings.HasPrefix(strings.ToLower(objName), "http") {
		return objName
	}
	// 创建OSSClient实例
	client, _ := oss.New(conf.Conf.Oss.Endpoint, conf.Conf.Oss.AccessKeyID, conf.Conf.Oss.AccessKeySecret)
	// 获取存储空间
	bucket, _ := client.Bucket(conf.Conf.Oss.BucketName)
	// 获取带签名的资源url
	signUrl, _ = bucket.SignURL(objName, oss.HTTPGet, int64(time.Hour.Seconds()))
	return
}

func adaptBizLicenseInfo(info *dto.BusinessLicenseInfoDTO) (r *wxpay.BizLicenseInfo) {
	if info == nil {
		return
	}
	r = &wxpay.BizLicenseInfo{
		BusinessLicenseCopy:   info.BusinessLicenseCopy,
		BusinessLicenseNumber: info.BusinessLicenseNumber,
		MerchantName:          info.MerchantName,
		LegalPerson:           info.LegalPerson,
		CompanyAddress:        info.CompanyAddress,
		BusinessTime:          info.BusinessTime,
		CopyUrl:               buildOssUrl(info.CopyOssName),
	}
	return
}

func adaptOrganizationCertInfo(info *dto.OrganizationCertInfoDTO) (r *wxpay.OrganizationCertInfo) {
	if info == nil {
		return
	}
	r = &wxpay.OrganizationCertInfo{
		OrganizationCopy:   info.OrganizationCopy,
		OrganizationNumber: info.OrganizationNumber,
		OrganizationTime:   info.OrganizationTime,
		CopyUrl:            buildOssUrl(info.CopyOssName),
	}
	return
}

func adaptIdCardInfo(info *dto.IDCardInfoDTO) (r *wxpay.IDCardInfo) {
	if info == nil {
		return
	}
	r = &wxpay.IDCardInfo{
		IdCardCopy:      info.IDCardCopy,
		IdCardNational:  info.IDCardNational,
		IdCardName:      info.IDCardName,
		IdCardNumber:    info.IDCardNumber,
		IdCardValidTime: info.IDCardValidTime,
		CardUrl:         buildOssUrl(info.CardCopyOssName),
		NationalUrl:     buildOssUrl(info.NationalCopyOssName),
	}
	return
}

func adaptIdDocInfo(info *dto.IDDocInfoDTO) (r *wxpay.IDDocInfo) {
	if info == nil {
		return
	}
	r = &wxpay.IDDocInfo{
		IdDocName:    info.IDDocName,
		IdDocNumber:  info.IDDocNumber,
		IdDocCopy:    info.IDDocCopy,
		DocPeriodEnd: info.DocPeriodEnd,
		CopyUrl:      buildOssUrl(info.CopyOssName),
	}
	return
}
func adaptAccountInfo(info *dto.AccountInfoDTO) (r *wxpay.AccountInfo) {
	if info == nil {
		return
	}
	r = &wxpay.AccountInfo{
		BankAccountType: info.BankAccountType,
		AccountBank:     info.AccountBank,
		AccountName:     info.AccountName,
		BankAddressCode: info.BankAddressCode,
		BankBranchId:    info.BankBranchID,
		BankName:        info.BankName,
		AccountNumber:   info.AccountNumber,
	}
	return
}
func adaptContactInfo(info dto.ContactInfoDTO) (r *wxpay.ContactInfo) {
	r = &wxpay.ContactInfo{
		ContactType:         info.ContactType,
		ContactName:         info.ContactName,
		ContactIdCardNumber: info.ContactIDCardNumber,
		MobilePhone:         info.MobilePhone,
		ContactEmail:        info.ContactEmail,
	}
	return
}
func adaptSalesSceneInfo(info dto.SalesSceneInfoDTO) (r *wxpay.SalesSceneInfo) {
	r = &wxpay.SalesSceneInfo{
		StoreName:           info.StoreName,
		StoreUrl:            info.StoreUrl,
		StoreQrCode:         info.StoreQrCode,
		MiniProgramSubAppid: info.MiniProgramSubAppID,
	}
	return
}
func adaptAccountValidation(info *dto.AccountValidationDTO) (r *wxpay.AccountValidation) {
	if info == nil {
		return
	}
	r = &wxpay.AccountValidation{
		AccountName:              info.AccountName,
		AccountNo:                info.AccountNo,
		PayAmount:                info.PayAmount,
		DestinationAccountNumber: info.DestinationAccountNumber,
		DestinationAccountName:   info.DestinationAccountName,
		DestinationAccountBank:   info.DestinationAccountBank,
		City:                     info.City,
		Remark:                   info.Remark,
		Deadline:                 info.Deadline,
	}
	return
}
func adaptAuditDetail(info *dto.AuditDetailDTO) (r []*wxpay.AuditDetail) {
	if info == nil {
		return
	}
	r = make([]*wxpay.AuditDetail, len(*info))
	for i, d := range *info {
		r[i] = &wxpay.AuditDetail{
			ParamName:    d.ParamName,
			RejectReason: d.RejectReason,
		}
	}
	return
}

// 查询申请 GET /api/v1/wxpay/applyment/{apply_no}
func (s *Server) ApplymentQuery(ctx context.Context, req *wxpay.ApplymentQueryRequest) (*wxpay.ApplymentQueryResponse, error) {
	op := merrors.Op("ApplymentQuery")

	res, err := service.NewApplymentService(s.d).Query(ctx, req.BrandId, req.ApplyNo, req.Force)
	if err != nil {
		return nil, merrors.E(op, merrors.Invalid, err)
	}
	applyInfo := *res.ApplymentInfo
	return &wxpay.ApplymentQueryResponse{
		ApplyType:            res.ApplymentType,
		MchId:                res.MchID,
		OrganizationType:     applyInfo.OrganizationType,
		BizLicenseInfo:       adaptBizLicenseInfo(applyInfo.BusinessLicenseInfo),
		OrganizationCertInfo: adaptOrganizationCertInfo(applyInfo.OrganizationCertInfo),
		IdDocType:            applyInfo.IDDocType,
		IdCardInfo:           adaptIdCardInfo(applyInfo.IDCardInfo),
		IdDocInfo:            adaptIdDocInfo(applyInfo.IDDocInfo),
		NeedAccountInfo:      applyInfo.NeedAccountInfo,
		AccountInfo:          adaptAccountInfo(applyInfo.AccountInfo),
		ContactInfo:          adaptContactInfo(applyInfo.ContactInfo),
		SalesSceneInfo:       adaptSalesSceneInfo(applyInfo.SalesSceneInfo),
		MerchantShortname:    applyInfo.MerchantShortname,
		Qualifications:       applyInfo.Qualifications,
		BusinessAdditionPics: applyInfo.BusinessAdditionPics,
		BusinessAdditionDesc: applyInfo.BusinessAdditionDesc,
		BrandId:              res.BrandID,
		WxApplymentId:        res.WxApplymentID,
		ApplyState:           res.ApplyState,
		ApplyStateDesc:       res.ApplyStateDesc,
		SignUrl:              res.SignURL,
		AccountValidation:    adaptAccountValidation(res.AccountValidation),
		SubMchId:             res.SubMchID,
		AuditDetails:         adaptAuditDetail(&res.AuditDetail),
		LegalValidationUrl:   res.LegalValidationURL,
		CreateTime:           util.TimePtrToString(&res.CreateTime, util.LayoutSecondWithTimeZoneAndT),
		UpdateTime:           util.TimePtrToString(&res.UpdateTime, util.LayoutSecondWithTimeZoneAndT),
	}, nil
}

func (s *Server) convertSubContactDTO(p *wxpay.ContactInfoV2) *dto.ContactInfoV2DTO {
	if p == nil {
		return nil
	}
	return &dto.ContactInfoV2DTO{
		ContactName:     p.ContactName,
		ContactIdNumber: p.ContactIdNumber,
		MobilePhone:     p.MobilePhone,
		ContactEmail:    p.ContactEmail,
	}
}

func (s *Server) getObjectNameFromCache(ctx context.Context, key string) (string, error) {
	if key == "" {
		return "", nil
	}
	op := "getObjectNameFromCache"
	objName, err := s.redis.Get(ctx, key).Result()
	if err != nil || objName == "" {
		return "", merrors.E(op, merrors.Invalid, merrors.ErrRedisClient, "找不到对应资源的oss对象名称")
	}
	return objName, nil
}

func (s *Server) convertBusinessLicenseInfoDTO(ctx context.Context, p *wxpay.BusinessLicenseInfo) (*dto.BusinessLicenseInfoV2DTO, error) {
	if p == nil {
		return nil, nil
	}
	ossCopy, err := s.getObjectNameFromCache(ctx, p.LicenseCopy)
	if err != nil {
		return nil, err
	}
	return &dto.BusinessLicenseInfoV2DTO{
		LicenseCopy:    p.LicenseCopy,
		OssLicenseCopy: ossCopy,
		LicenseNumber:  p.LicenseNumber,
		MerchantName:   p.MerchantName,
		LegalPerson:    p.LegalPerson,
	}, nil
}

func (s *Server) convertSubCertificationInfoDTO(ctx context.Context, p *wxpay.CertificateInfo) (*dto.CertificateInfoDTO, error) {
	if p == nil {
		return nil, nil
	}
	ossCopy, err := s.getObjectNameFromCache(ctx, p.CertCopy)
	if err != nil {
		return nil, err
	}
	return &dto.CertificateInfoDTO{
		CertCopy:       p.CertCopy,
		OssCertCopy:    ossCopy,
		CertType:       p.CertType,
		CertNumber:     p.CertNumber,
		MerchantName:   p.MerchantName,
		CompanyAddress: p.CompanyAddress,
		LegalPerson:    p.LegalPerson,
		PeriodBegin:    p.PeriodBegin,
		PeriodEnd:      p.PeriodEnd,
	}, nil
}

func (s *Server) convertSubOrganizationInfoDTO(ctx context.Context, p *wxpay.OrganizationInfo) (*dto.OrganizationInfoDTO, error) {
	if p == nil {
		return nil, nil
	}
	ossCopy, err := s.getObjectNameFromCache(ctx, p.OrganizationCopy)
	if err != nil {
		return nil, err
	}
	return &dto.OrganizationInfoDTO{
		OrganizationCopy:    p.OrganizationCopy,
		OssOrganizationCopy: ossCopy,
		OrganizationCode:    p.OrganizationCode,
		OrgPeriodBegin:      p.OrgPeriodBegin,
		OrgPeriodEnd:        p.OrgPeriodEnd,
	}, nil
}

func (s *Server) convertSubIdentityInfoDTO(ctx context.Context, p *wxpay.IdentityInfo) (*dto.IdentityInfoDTO, error) {
	if p == nil {
		return nil, nil
	}
	r := &dto.IdentityInfoDTO{
		IdDocType:     p.IdDocType,
		IdCardInfoDTO: nil,
		IdDocInfoDTO:  nil,
		Owner:         p.Owner,
	}
	if p.IdCardInfo != nil {
		ossCopy, err := s.getObjectNameFromCache(ctx, p.IdCardInfo.IdCardCopy)
		if err != nil {
			return nil, err
		}
		ossNation, err := s.getObjectNameFromCache(ctx, p.IdCardInfo.IdCardNational)
		if err != nil {
			return nil, err
		}
		r.IdCardInfoDTO = &dto.IdCardInfoV2DTO{
			IdCardCopy:        p.IdCardInfo.IdCardCopy,
			OssIdCardCopy:     ossCopy,
			IdCardNational:    p.IdCardInfo.IdCardNational,
			OssIdCardNational: ossNation,
			IdCardName:        p.IdCardInfo.IdCardName,
			IdCardNumber:      p.IdCardInfo.IdCardNumber,
			CardPeriodBegin:   p.IdCardInfo.CardPeriodBegin,
			CardPeriodEnd:     p.IdCardInfo.CardPeriodEnd,
		}
	}
	if p.IdDocInfo != nil {
		ossCopy, err := s.getObjectNameFromCache(ctx, p.IdDocInfo.IdDocCopy)
		if err != nil {
			return nil, err
		}
		r.IdDocInfoDTO = &dto.IDDocInfoV2DTO{
			IdDocCopy:      p.IdDocInfo.IdDocCopy,
			OssIdDocCopy:   ossCopy,
			IdDocName:      p.IdDocInfo.IdDocName,
			IdDocNumber:    p.IdDocInfo.IdDocNumber,
			DocPeriodBegin: p.IdDocInfo.DocPeriodBegin,
			DocPeriodEnd:   p.IdDocInfo.DocPeriodEnd,
		}
	}
	return r, nil
}

func (s *Server) covertSubUboInfoDTO(ctx context.Context, p *wxpay.UboInfo) (*dto.UboInfoDTO, error) {
	if p == nil {
		return nil, nil
	}
	ossCopy, err := s.getObjectNameFromCache(ctx, p.IdCardCopy)
	if err != nil {
		return nil, err
	}
	ossNation, err := s.getObjectNameFromCache(ctx, p.IdCardNational)
	if err != nil {
		return nil, err
	}
	ossDoc, err := s.getObjectNameFromCache(ctx, p.IdDocCopy)
	if err != nil {
		return nil, err
	}
	return &dto.UboInfoDTO{
		IdType:            p.IdType,
		IdCardCopy:        p.IdDocCopy,
		OssIdCardCopy:     ossCopy,
		IdCardNational:    p.IdCardNational,
		OssIdCardNational: ossNation,
		IdDocCopy:         p.IdDocCopy,
		OssIdDocCopy:      ossDoc,
		Name:              p.Name,
		IdNumber:          p.IdNumber,
		IdPeriodBegin:     p.IdPeriodBegin,
		IdPeriodEnd:       p.IdPeriodEnd,
	}, nil
}

func (s *Server) convertSubSubjectDTO(ctx context.Context, p *wxpay.SubjectInfo) (*dto.SubjectInfoDTO, error) {
	if p == nil {
		return nil, nil
	}
	ossCert, err := s.getObjectNameFromCache(ctx, p.CertificateLetterCopy)
	if err != nil {
		return nil, err
	}
	r := &dto.SubjectInfoDTO{
		SubjectType:              p.SubjectType,
		CertificateLetterCopy:    p.CertificateLetterCopy,
		OssCertificateLetterCopy: ossCert,
		IdentityInfoDTO:          nil,
		UboInfoDTO:               nil,
	}
	r.BusinessLicenseInfoDTO, err = s.convertBusinessLicenseInfoDTO(ctx, p.BusinessLicenseInfo)
	if err != nil {
		return nil, err
	}
	r.CertificateInfoDTO, err = s.convertSubCertificationInfoDTO(ctx, p.CertificateInfo)
	if err != nil {
		return nil, err
	}
	r.OrganizationInfoDTO, err = s.convertSubOrganizationInfoDTO(ctx, p.OrganizationInfo)
	if err != nil {
		return nil, err
	}
	r.IdentityInfoDTO, err = s.convertSubIdentityInfoDTO(ctx, p.IdentityInfo)
	if err != nil {
		return nil, err
	}
	r.UboInfoDTO, err = s.covertSubUboInfoDTO(ctx, p.UboInfo)
	if err != nil {
		return nil, err
	}
	r.MicroBizInfoDTO, err = s.convertMicroBizInfo(ctx, p.MicroBizInfo)
	return r, nil
}

func (s *Server) getOssObjectNames(ctx context.Context, pics []string) ([]string, error) {
	ossPics := make([]string, len(pics))
	for idx, pic := range pics {
		o, err := s.getObjectNameFromCache(ctx, pic)
		if err != nil {
			return nil, err
		}
		ossPics[idx] = o
	}
	return ossPics, nil
}

func (s *Server) convertSubSalesInfoDTO(ctx context.Context, p *wxpay.SalesInfo) (*dto.SalesInfoDTO, error) {
	if p == nil {
		return nil, nil
	}
	r := &dto.SalesInfoDTO{
		SalesScenesType: p.SalesScenesType,
	}
	if p.BizStoreInfo != nil {
		ossEnts, err := s.getOssObjectNames(ctx, p.BizStoreInfo.StoreEntrancePic)
		if err != nil {
			return nil, err
		}
		ossIndoors, err := s.getOssObjectNames(ctx, p.BizStoreInfo.IndoorPic)
		if err != nil {
			return nil, err
		}
		r.BizStoreInfo = &dto.BizStoreInfoDTO{
			BizStoreName:        p.BizStoreInfo.BizStoreName,
			BizAddressCode:      p.BizStoreInfo.BizAddressCode,
			BizStoreAddress:     p.BizStoreInfo.BizStoreAddress,
			StoreEntrancePic:    p.BizStoreInfo.StoreEntrancePic,
			OssStoreEntrancePic: ossEnts,
			IndoorPic:           p.BizStoreInfo.IndoorPic,
			OssIndoorPic:        ossIndoors,
			BizSubAppId:         p.BizStoreInfo.BizSubAppId,
		}
	}
	if p.MpInfo != nil {
		ossPics, err := s.getOssObjectNames(ctx, p.MpInfo.MpPics)
		if err != nil {
			return nil, err
		}
		r.MpInfo = &dto.MpInfoDTO{
			MpAppId:    p.MpInfo.MpAppId,
			MpSubAppId: p.MpInfo.MpSubAppId,
			MpPics:     p.MpInfo.MpPics,
			OssMpPics:  ossPics,
		}
	}
	if p.MiniProgramInfo != nil {
		ossPics, err := s.getOssObjectNames(ctx, p.MiniProgramInfo.MiniProgramPics)
		if err != nil {
			return nil, err
		}
		r.MiniProgramInfo = &dto.MiniProgramInfoDTO{
			MiniProgramAppId:    p.MiniProgramInfo.MiniProgramAppId,
			MiniProgramSubAppId: p.MiniProgramInfo.MiniProgramSubAppId,
			MiniProgramPics:     p.MiniProgramInfo.MiniProgramPics,
			OssMiniProgramPics:  ossPics,
		}
	}
	if p.AppInfo != nil {
		ossPics, err := s.getOssObjectNames(ctx, p.AppInfo.AppPics)
		if err != nil {
			return nil, err
		}
		r.AppInfo = &dto.AppInfoDTO{
			AppAppId:    p.AppInfo.AppAppId,
			AppSubAppId: p.AppInfo.AppSubAppId,
			AppPics:     p.AppInfo.AppPics,
			OssAppPics:  ossPics,
		}
	}
	if p.WebInfo != nil {
		ossAuth, err := s.getObjectNameFromCache(ctx, p.WebInfo.WebAuthorisation)
		if err != nil {
			return nil, err
		}
		r.WebInfo = &dto.WebInfoDTO{
			Domain:              p.WebInfo.Domain,
			WebAuthorisation:    p.WebInfo.WebAuthorisation,
			OssWebAuthorisation: ossAuth,
			WebAppId:            p.WebInfo.WebAppId,
		}
	}
	if p.WeworkInfo != nil {
		ossPics, err := s.getOssObjectNames(ctx, p.WeworkInfo.WeworkPics)
		if err != nil {
			return nil, err
		}
		r.WeworkInfo = &dto.WeworkInfoDTO{
			SubCorpId:     p.WeworkInfo.SubCorpId,
			WeworkPics:    p.WeworkInfo.WeworkPics,
			OssWeworkPics: ossPics,
		}
	}
	return r, nil
}

func (s *Server) convertSubBusinessInfoDTO(ctx context.Context, p *wxpay.BusinessInfo) (*dto.BusinessInfoDTO, error) {
	if p == nil {
		return nil, nil
	}
	r := &dto.BusinessInfoDTO{
		MerchantShortname: p.MerchantShortname,
		ServicePhone:      p.ServicePhone,
	}
	var err error
	r.SalesInfoDTO, err = s.convertSubSalesInfoDTO(ctx, p.SalesInfo)
	if err != nil {
		return nil, err
	}
	return r, nil
}

func (s *Server) convertSettlementInfoDTO(ctx context.Context, p *wxpay.SettlementInfo) (*dto.SettlementInfoDTO, error) {
	if p == nil {
		return nil, nil
	}
	ossQ, err := s.getOssObjectNames(ctx, p.Qualifications)
	if err != nil {
		return nil, err
	}
	ossA, err := s.getOssObjectNames(ctx, p.ActivitiesAdditions)
	if err != nil {
		return nil, err
	}
	return &dto.SettlementInfoDTO{
		SettlementId:           p.SettlementId,
		QualificationType:      p.QualificationType,
		Qualifications:         p.Qualifications,
		OssQualifications:      ossQ,
		ActivitiesId:           p.ActivitiesId,
		ActivitiesRate:         p.ActivitiesRate,
		ActivitiesAdditions:    p.ActivitiesAdditions,
		OssActivitiesAdditions: ossA,
	}, nil
}

func (s *Server) convertBankAccountInfoDTO(p *wxpay.AccountInfo) *dto.AccountInfoDTO {
	if p == nil {
		return nil
	}
	return &dto.AccountInfoDTO{
		BankAccountType: p.BankAccountType,
		AccountBank:     p.AccountBank,
		AccountName:     p.AccountName,
		BankAddressCode: p.BankAddressCode,
		BankBranchID:    p.BankBranchId,
		BankName:        p.BankName,
		AccountNumber:   p.AccountNumber,
	}
}

func (s *Server) convertAdditionInfoDTO(ctx context.Context, p *wxpay.AdditionInfo) (*dto.AdditionInfoDTO, error) {
	if p == nil {
		return nil, nil
	}
	ossC, err := s.getObjectNameFromCache(ctx, p.LegalPersonCommitment)
	if err != nil {
		return nil, err
	}
	ossV, err := s.getObjectNameFromCache(ctx, p.LegalPersonVideo)
	if err != nil {
		return nil, err
	}
	ossPics, err := s.getOssObjectNames(ctx, p.BusinessAdditionPics)
	if err != nil {
		return nil, err
	}
	return &dto.AdditionInfoDTO{
		LegalPersonCommitment:    p.LegalPersonCommitment,
		OssLegalPersonCommitment: ossC,
		LegalPersonVideo:         p.LegalPersonVideo,
		OssLegalPersonVideo:      ossV,
		BusinessAdditionPics:     p.BusinessAdditionPics,
		OssBusinessAdditionPics:  ossPics,
		BusinessAdditionMsg:      p.BusinessAdditionMsg,
	}, nil
}

func (s *Server) convertMicroStoreInfo(ctx context.Context, p *wxpay.MicroStoreInfo) (*dto.MicroStoreInfoDTO, error) {
	if p == nil {
		return nil, nil
	}
	var err error
	r := &dto.MicroStoreInfoDTO{
		MicroName:           p.MicroName,
		MicroAddressCode:    p.MicroAddressCode,
		MicroAddress:        p.MicroAddress,
		StoreEntrancePic:    p.MicroEntrancePic,
		OssStoreEntrancePic: "",
		MicroIndoorCopy:     p.MicroIndoorCopy,
		OssMicroIndoorCopy:  "",
		StoreLongitude:      p.StoreLongitude,
		StoreLatitude:       p.StoreLatitude,
	}
	r.OssStoreEntrancePic, err = s.getObjectNameFromCache(ctx, p.MicroEntrancePic)
	if err != nil {
		return nil, err
	}
	r.OssMicroIndoorCopy, err = s.getObjectNameFromCache(ctx, p.MicroIndoorCopy)
	if err != nil {
		return nil, err
	}
	return r, nil
}

func (s *Server) convertMicroMobileInfo(ctx context.Context, p *wxpay.MicroMobileInfo) (*dto.MicroMobileInfoDTO, error) {
	if p == nil {
		return nil, nil
	}
	var err error
	r := &dto.MicroMobileInfoDTO{
		MicroMobileName:    p.MicroMobileName,
		MicroMobileCity:    p.MicroMobileCity,
		MicroMobileAddress: p.MicroMobileAddress,
		MicroMobilePics:    p.MicroMobilePics,
		OssMicroMobilePics: nil,
	}
	r.OssMicroMobilePics, err = s.getOssObjectNames(ctx, p.MicroMobilePics)
	if err != nil {
		return nil, err
	}
	return r, nil
}

func (s *Server) convertMicroOnlineInfo(ctx context.Context, p *wxpay.MicroOnlineInfo) (*dto.MicroOnlineInfoDTO, error) {
	if p == nil {
		return nil, nil
	}
	var err error
	r := &dto.MicroOnlineInfoDTO{
		MicroOnlineStore: p.MicroOnlineStore,
		MicroEcName:      p.MicroEcName,
		MicroQrcode:      p.MicroQrcode,
		OssMicroQrcode:   "",
		MicroLink:        p.MicroLink,
	}
	r.OssMicroQrcode, err = s.getObjectNameFromCache(ctx, p.MicroQrcode)
	if err != nil {
		return nil, err
	}
	return r, nil
}

func (s *Server) convertMicroBizInfo(ctx context.Context, p *wxpay.MicroBizInfo) (*dto.MicroBizInfoDTO, error) {
	if p == nil {
		return nil, nil
	}
	var err error
	r := &dto.MicroBizInfoDTO{
		MicroBizType:       p.MicroBizType,
		MicroStoreInfoDTO:  nil,
		MicroMobileInfoDTO: nil,
		MicroOnlineInfoDTO: nil,
	}
	r.MicroStoreInfoDTO, err = s.convertMicroStoreInfo(ctx, p.MicroStoreInfo)
	if err != nil {
		return nil, err
	}
	r.MicroOnlineInfoDTO, err = s.convertMicroOnlineInfo(ctx, p.MicroOnlineInfo)
	if err != nil {
		return nil, err
	}
	r.MicroMobileInfoDTO, err = s.convertMicroMobileInfo(ctx, p.MicroMobileInfo)
	if err != nil {
		return nil, err
	}
	return r, nil
}

func (s *Server) convertSubApplymentInfoDTO(ctx context.Context, p *wxpay.SubMchApplymentSubmitRequest) (*dto.SubMchApplymentInfoDTO, error) {
	if p == nil {
		return nil, nil
	}
	var err error
	r := &dto.SubMchApplymentInfoDTO{
		SettlementInfoDTO:  nil,
		BankAccountInfoDTO: nil,
		AdditionInfoDTO:    nil,
	}
	r.ContactInfoDTO = s.convertSubContactDTO(p.ContactInfo)
	r.SubjectInfoDTO, err = s.convertSubSubjectDTO(ctx, p.SubjectInfo)
	if err != nil {
		return nil, err
	}
	r.BusinessInfoDTO, err = s.convertSubBusinessInfoDTO(ctx, p.BusinessInfo)
	if err != nil {
		return nil, err
	}
	r.SettlementInfoDTO, err = s.convertSettlementInfoDTO(ctx, p.SettlementInfo)
	if err != nil {
		return nil, err
	}
	r.BankAccountInfoDTO = s.convertBankAccountInfoDTO(p.BankAccountInfo)
	r.AdditionInfoDTO, err = s.convertAdditionInfoDTO(ctx, p.AdditionInfo)
	if err != nil {
		return nil, err
	}
	r.SetSettlementId()
	return r, nil
}

func (s *Server) buildSubMchApplymentDTOFromRequest(ctx context.Context, p *wxpay.SubMchApplymentSubmitRequest) (*dto.SubMchApplymentDTO, error) {
	r := &dto.SubMchApplymentDTO{
		BizApplyNo:    p.BizApplyNo,
		BrandID:       p.BrandId,
		MchID:         p.MchId,
		ApplymentType: "sub",
		CreateTime:    time.Time{},
		UpdateTime:    time.Time{},
	}
	var err error
	r.SubApplymentInfo, err = s.convertSubApplymentInfoDTO(ctx, p)
	if err != nil {
		return nil, err
	}
	return r, nil
}

// 微信特约商户进件
func (s *Server) WxSubMchApplymentSubmit(ctx context.Context, req *wxpay.SubMchApplymentSubmitRequest) (*wxpay.SubMchApplymentSubmitResponse, error) {
	if req == nil {
		return nil, nil
	}
	apply, err := s.buildSubMchApplymentDTOFromRequest(ctx, req)
	if err != nil {
		return nil, err
	}
	res, err := service.NewApplymentService(s.d).SubMchApplymentSubmit(ctx, apply)
	if err != nil {
		return nil, err
	}
	return &wxpay.SubMchApplymentSubmitResponse{
		ApplyNo:        res.ApplyNo,
		ApplyState:     res.ApplyState,
		ApplyStateDesc: res.ApplyStateDesc,
	}, nil
}

func (s *Server) WxSubMchApplymentReSubmit(ctx context.Context, req *wxpay.SubMchApplymentSubmitRequest) (*wxpay.SubMchApplymentSubmitResponse, error) {
	if req == nil {
		return nil, nil
	}
	apply, err := s.buildSubMchApplymentDTOFromRequest(ctx, req)
	if err != nil {
		return nil, err
	}
	res, err := service.NewApplymentService(s.d).SubMchApplymentReSubmit(ctx, apply)
	if err != nil {
		return nil, err
	}
	return &wxpay.SubMchApplymentSubmitResponse{
		ApplyNo: res.ApplyNo,
	}, nil
}

func adaptContactInfoV2(info *dto.ContactInfoV2DTO) *wxpay.ContactInfoV2 {
	if info == nil {
		return nil
	}
	return &wxpay.ContactInfoV2{
		ContactName:     info.ContactName,
		ContactIdNumber: info.ContactIdNumber,
		MobilePhone:     info.MobilePhone,
		ContactEmail:    info.ContactEmail,
	}
}

func adaptSubjectInfo(info *dto.SubjectInfoDTO) *wxpay.SubjectInfo {
	r := &wxpay.SubjectInfo{
		SubjectType:              info.SubjectType,
		CertificateLetterCopy:    info.CertificateLetterCopy,
		CertificateLetterCopyUrl: buildOssUrl(info.OssCertificateLetterCopy),
	}
	if info.BusinessLicenseInfoDTO != nil {
		b := info.BusinessLicenseInfoDTO
		r.BusinessLicenseInfo = &wxpay.BusinessLicenseInfo{
			LicenseCopy:    b.LicenseCopy,
			LicenseNumber:  b.LicenseNumber,
			MerchantName:   b.MerchantName,
			LegalPerson:    b.LegalPerson,
			LicenseCopyUrl: buildOssUrl(b.OssLicenseCopy),
		}
	}
	if info.CertificateInfoDTO != nil {
		c := info.CertificateInfoDTO
		r.CertificateInfo = &wxpay.CertificateInfo{
			CertCopy:       c.CertCopy,
			CertType:       c.CertType,
			CertNumber:     c.CertNumber,
			MerchantName:   c.MerchantName,
			CompanyAddress: c.CompanyAddress,
			LegalPerson:    c.LegalPerson,
			PeriodBegin:    c.PeriodBegin,
			PeriodEnd:      c.PeriodEnd,
			CertCopyUrl:    buildOssUrl(c.OssCertCopy),
		}
	}
	if info.IdentityInfoDTO != nil {
		i := info.IdentityInfoDTO
		r.IdentityInfo = &wxpay.IdentityInfo{
			IdDocType: i.IdDocType,
			Owner:     i.Owner,
		}
		if r.IdentityInfo.IdCardInfo != nil {
			r.IdentityInfo.IdCardInfo = &wxpay.IDCardInfoV2{
				IdCardCopy:      i.IdCardInfoDTO.IdCardCopy,
				IdCardNational:  i.IdCardInfoDTO.IdCardNational,
				IdCardName:      i.IdCardInfoDTO.IdCardName,
				IdCardNumber:    i.IdCardInfoDTO.IdCardNumber,
				CardPeriodBegin: i.IdCardInfoDTO.CardPeriodBegin,
				CardPeriodEnd:   i.IdCardInfoDTO.CardPeriodEnd,
				CardCopyUrl:     buildOssUrl(i.IdCardInfoDTO.OssIdCardCopy),
				NationalCopyUrl: buildOssUrl(i.IdCardInfoDTO.OssIdCardNational),
			}
		}
		if r.IdentityInfo.IdDocInfo != nil {
			r.IdentityInfo.IdDocInfo = &wxpay.IDDocInfoV2{
				IdDocCopy:      i.IdDocInfoDTO.IdDocCopy,
				IdDocName:      i.IdDocInfoDTO.IdDocName,
				IdDocNumber:    i.IdDocInfoDTO.IdDocNumber,
				DocPeriodBegin: i.IdDocInfoDTO.DocPeriodBegin,
				DocPeriodEnd:   i.IdDocInfoDTO.DocPeriodEnd,
				DocCopyUrl:     buildOssUrl(i.IdDocInfoDTO.OssIdDocCopy),
			}
		}
	}
	if info.UboInfoDTO != nil {
		u := info.UboInfoDTO
		r.UboInfo = &wxpay.UboInfo{
			IdType:          u.IdType,
			IdCardCopy:      u.IdCardCopy,
			IdCardNational:  u.IdCardNational,
			IdDocCopy:       u.IdDocCopy,
			Name:            u.Name,
			IdNumber:        u.IdNumber,
			IdPeriodBegin:   u.IdPeriodBegin,
			IdPeriodEnd:     u.IdPeriodEnd,
			CardCopyUrl:     buildOssUrl(u.OssIdCardCopy),
			CardNationalUrl: buildOssUrl(u.OssIdCardNational),
			DocCopyUrl:      buildOssUrl(u.OssIdDocCopy),
		}
	}
	if info.MicroBizInfoDTO != nil {
		m := info.MicroBizInfoDTO
		r := &wxpay.MicroBizInfo{
			MicroBizType:    m.MicroBizType,
			MicroStoreInfo:  nil,
			MicroMobileInfo: nil,
			MicroOnlineInfo: nil,
		}
		if m.MicroStoreInfoDTO != nil {
			r.MicroStoreInfo = &wxpay.MicroStoreInfo{
				MicroName:           m.MicroStoreInfoDTO.MicroName,
				MicroAddressCode:    m.MicroStoreInfoDTO.MicroAddressCode,
				MicroAddress:        m.MicroStoreInfoDTO.MicroAddress,
				MicroEntrancePic:    m.MicroStoreInfoDTO.StoreEntrancePic,
				MicroEntrancePicUrl: buildOssUrl(m.MicroStoreInfoDTO.OssStoreEntrancePic),
				MicroIndoorCopy:     m.MicroStoreInfoDTO.MicroIndoorCopy,
				MicroIndoorCopyUrl:  buildOssUrl(m.MicroStoreInfoDTO.OssMicroIndoorCopy),
				StoreLongitude:      m.MicroStoreInfoDTO.StoreLongitude,
				StoreLatitude:       m.MicroStoreInfoDTO.StoreLatitude,
			}
		}
		if m.MicroMobileInfoDTO != nil {
			r.MicroMobileInfo = &wxpay.MicroMobileInfo{
				MicroMobileName:    m.MicroMobileInfoDTO.MicroMobileName,
				MicroMobileCity:    m.MicroMobileInfoDTO.MicroMobileCity,
				MicroMobileAddress: m.MicroMobileInfoDTO.MicroMobileAddress,
				MicroMobilePics:    m.MicroMobileInfoDTO.OssMicroMobilePics,
				MicroMobilePicsUrl: getOssUrls(m.MicroMobileInfoDTO.OssMicroMobilePics),
			}
		}
		if m.MicroOnlineInfoDTO != nil {
			r.MicroOnlineInfo = &wxpay.MicroOnlineInfo{
				MicroOnlineStore: m.MicroOnlineInfoDTO.MicroOnlineStore,
				MicroEcName:      m.MicroOnlineInfoDTO.MicroEcName,
				MicroQrcode:      m.MicroOnlineInfoDTO.MicroQrcode,
				MicroQrcodeUrl:   buildOssUrl(m.MicroOnlineInfoDTO.OssMicroQrcode),
				MicroLink:        m.MicroOnlineInfoDTO.MicroLink,
			}
		}
	}
	return r
}

func getOssUrls(objNames []string) []string {
	ret := make([]string, len(objNames))
	for idx, n := range objNames {
		ret[idx] = buildOssUrl(n)
	}
	return ret
}

func adaptBusinessInfo(info *dto.BusinessInfoDTO) *wxpay.BusinessInfo {
	if info == nil {
		return nil
	}
	r := &wxpay.BusinessInfo{
		MerchantShortname: info.MerchantShortname,
		ServicePhone:      info.ServicePhone,
		SalesInfo:         nil,
	}
	if info.SalesInfoDTO != nil {
		s := info.SalesInfoDTO
		r.SalesInfo = &wxpay.SalesInfo{
			SalesScenesType: s.SalesScenesType,
		}
		if s.BizStoreInfo != nil {
			r.SalesInfo.BizStoreInfo = &wxpay.BizStoreInfo{
				BizStoreName:        s.BizStoreInfo.BizStoreName,
				BizAddressCode:      s.BizStoreInfo.BizAddressCode,
				BizStoreAddress:     s.BizStoreInfo.BizStoreAddress,
				StoreEntrancePic:    s.BizStoreInfo.StoreEntrancePic,
				IndoorPic:           s.BizStoreInfo.IndoorPic,
				BizSubAppId:         s.BizStoreInfo.BizSubAppId,
				StoreEntrancePicUrl: getOssUrls(s.BizStoreInfo.OssStoreEntrancePic),
				IndoorPicUrl:        getOssUrls(s.BizStoreInfo.OssIndoorPic),
			}
		}
		if s.MpInfo != nil {
			r.SalesInfo.MpInfo = &wxpay.MpInfo{
				MpAppId:    s.MpInfo.MpAppId,
				MpSubAppId: s.MpInfo.MpSubAppId,
				MpPics:     s.MpInfo.MpPics,
				MpPicsUrl:  getOssUrls(s.MpInfo.OssMpPics),
			}
		}
		if s.MiniProgramInfo != nil {
			r.SalesInfo.MiniProgramInfo = &wxpay.MiniProgramInfo{
				MiniProgramAppId:    s.MiniProgramInfo.MiniProgramAppId,
				MiniProgramSubAppId: s.MiniProgramInfo.MiniProgramSubAppId,
				MiniProgramPics:     s.MiniProgramInfo.MiniProgramPics,
				MiniProgramPicsUrl:  getOssUrls(s.MiniProgramInfo.OssMiniProgramPics),
			}
		}
		if s.AppInfo != nil {
			r.SalesInfo.AppInfo = &wxpay.AppInfo{
				AppAppId:    s.AppInfo.AppAppId,
				AppSubAppId: s.AppInfo.AppSubAppId,
				AppPics:     s.AppInfo.AppPics,
				AppPicsUrl:  getOssUrls(s.AppInfo.OssAppPics),
			}
		}
		if s.WebInfo != nil {
			r.SalesInfo.WebInfo = &wxpay.WebInfo{
				Domain:              s.WebInfo.Domain,
				WebAuthorisation:    s.WebInfo.WebAuthorisation,
				WebAppId:            s.WebInfo.WebAppId,
				WebAuthorisationUrl: buildOssUrl(s.WebInfo.OssWebAuthorisation),
			}
		}
		if s.WeworkInfo != nil {
			r.SalesInfo.WeworkInfo = &wxpay.WeworkInfo{
				SubCorpId:     s.WeworkInfo.SubCorpId,
				WeworkPics:    s.WeworkInfo.WeworkPics,
				WeworkPicsUrl: getOssUrls(s.WeworkInfo.OssWeworkPics),
			}
		}
	}
	return r
}

func adaptSettlementInfo(info *dto.SettlementInfoDTO) *wxpay.SettlementInfo {
	if info == nil {
		return nil
	}
	return &wxpay.SettlementInfo{
		SettlementId:           info.SettlementId,
		QualificationType:      info.QualificationType,
		Qualifications:         info.Qualifications,
		ActivitiesId:           info.ActivitiesId,
		ActivitiesRate:         info.ActivitiesRate,
		ActivitiesAdditions:    info.ActivitiesAdditions,
		QualificationsUrl:      getOssUrls(info.OssQualifications),
		ActivitiesAdditionsUrl: getOssUrls(info.OssActivitiesAdditions),
	}
}

func adaptAdditionInfo(info *dto.AdditionInfoDTO) *wxpay.AdditionInfo {
	if info == nil {
		return nil
	}
	return &wxpay.AdditionInfo{
		LegalPersonCommitment:    info.LegalPersonCommitment,
		LegalPersonVideo:         buildOssUrl(info.OssLegalPersonVideo),
		BusinessAdditionPics:     info.BusinessAdditionPics,
		BusinessAdditionMsg:      info.BusinessAdditionMsg,
		LegalPersonCommitmentUrl: buildOssUrl(info.OssLegalPersonCommitment),
		BusinessAdditionPicsUrl:  getOssUrls(info.OssBusinessAdditionPics),
	}
}

func adaptSubMchApplyResponse(res *dto.SubMchApplymentDTO) *wxpay.SubMchApplymentQueryResponse {
	if res == nil {
		return nil
	}
	r := &wxpay.SubMchApplymentQueryResponse{
		ApplyNo:        res.ApplyNo,
		BizApplyNo:     res.BizApplyNo,
		BrandId:        res.BrandID,
		MchId:          res.MchID,
		SubMchId:       res.SubMchID,
		SignUrl:        res.SignURL,
		ApplyState:     res.ApplyState,
		ApplyStateDesc: res.ApplyStateDesc,
		AdditionInfo:   nil,
		AuditDetails:   nil,
	}
	if res.SubApplymentInfo == nil {
		return r
	}
	r.ContactInfo = adaptContactInfoV2(res.SubApplymentInfo.ContactInfoDTO)
	r.SubjectInfo = adaptSubjectInfo(res.SubApplymentInfo.SubjectInfoDTO)
	r.BusinessInfo = adaptBusinessInfo(res.SubApplymentInfo.BusinessInfoDTO)
	r.SettlementInfo = adaptSettlementInfo(res.SubApplymentInfo.SettlementInfoDTO)
	r.BankAccountInfo = adaptAccountInfo(res.SubApplymentInfo.BankAccountInfoDTO)
	r.AdditionInfo = adaptAdditionInfo(res.SubApplymentInfo.AdditionInfoDTO)
	r.AuditDetails = adaptAuditDetail(&res.AuditDetail)
	return r
}

func (s *Server) WxSubMchApplymentQuery(ctx context.Context, req *wxpay.SubMchApplymentQueryRequest) (*wxpay.SubMchApplymentQueryResponse, error) {
	if req == nil {
		return nil, nil
	}
	res, err := service.NewApplymentService(s.d).SubMchApplymentQuery(ctx, req.BrandId, req.BizNo)
	if err != nil {
		return nil, err
	}
	return adaptSubMchApplyResponse(res), nil
}
